package org.nkumar.immortal.web;

import java.beans.XMLDecoder;
import java.io.BufferedInputStream;
import java.io.InputStream;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

final class ImmortalResourceURLProviderConfig
{
    private static final Logger LOG = Logger.getLogger(ImmortalResourceURLProvider.class.getName());
    private static final String EXT_RESOURCE_BASE_KEY = "extResourceBase";
    private static final String EXT_RESOURCE_BASE_SYS_PROP_NAME = "org.nkumar.immortal.web.extResourceBaseUrl";

    private final String extResourceBase;
    private final Map<String, String> RESOURCE_MAPPING_MAP;

    ImmortalResourceURLProviderConfig(InputStream in)
    {
        Map<String, Object> mappingConfig = null;
        if (in == null)
        {
            LOG.warning("Failed to load " + ImmortalResourceURLProvider.IMMORTAL_MAPPINGS_XML
                    + " file. Urls will not be replaced");
        }
        else
        {
            try
            {
                final XMLDecoder d = new XMLDecoder(new BufferedInputStream(in));
                mappingConfig = (Map<String, Object>) d.readObject();
                d.close();
            }
            catch (Exception e)
            {
                e.printStackTrace();
                LOG.warning("Failed to parse " + ImmortalResourceURLProvider.IMMORTAL_MAPPINGS_XML
                        + " file. Urls will not be replaced");
                mappingConfig = null;
            }
        }
        final Map<String, String> map1 = new HashMap<String, String>();
        if (mappingConfig != null && mappingConfig.get("mappings") != null)
        {
            final Map<String, String> mappings = (Map<String, String>) mappingConfig.get("mappings");
            map1.putAll(mappings);
        }
        RESOURCE_MAPPING_MAP = Collections.unmodifiableMap(map1);

        String resourceBase = getNormalizedUrl(System.getProperty(EXT_RESOURCE_BASE_SYS_PROP_NAME));
        if (resourceBase == null)
        {
            resourceBase = mappingConfig != null ? (String) mappingConfig.get(EXT_RESOURCE_BASE_KEY) : null;
            resourceBase = getNormalizedUrl(resourceBase);
        }
        extResourceBase = resourceBase;
    }

    private static String getNormalizedUrl(String resourceBase)
    {
        if (resourceBase != null)
        {
            resourceBase = resourceBase.trim();
            if (resourceBase.length() == 0)
            {
                return null;
            }
            if (resourceBase.endsWith("/"))
            {
                resourceBase = resourceBase.substring(0, resourceBase.length() - 1);
            }
        }
        return resourceBase;
    }

    String getVersionedUrlFromRequest(final String oldUrl, final String contextPath)
    {
        if (!oldUrl.startsWith("/"))
        {
            throw new IllegalArgumentException("url passed must start with a slash, ie it must be an absolute path");
        }
        final String newUrl = RESOURCE_MAPPING_MAP.get(oldUrl);
        if (newUrl == null && LOG.isLoggable(Level.FINE))
        {
            LOG.fine("no mapping found for " + oldUrl);
        }
        if (newUrl != null && LOG.isLoggable(Level.FINER))
        {
            LOG.finer(oldUrl + " is mapped to " + newUrl);
        }
        final String url = newUrl == null ? oldUrl : newUrl;
        return extResourceBase == null ? contextPath + url : extResourceBase + url;
    }
}
